/*
 * LinesFrame.java
 * 
 * Created by demory on Nov 28, 2009, 10:26:19 PM
 * 
 * Copyright 2008 David D. Emory
 * 
 * This file is part of Five Points. See <http://www.fpdev.org> for
 * additional information regarding the project.
 * 
 * Five Points is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Five Points is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Five Points.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.fpdev.apps.cart.gui.control;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.BevelBorder;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import org.fpdev.apps.cart.CartEvent;
import org.fpdev.apps.cart.CartEvent.Type;
import org.fpdev.apps.cart.CartEventProcessor;
import org.fpdev.apps.cart.Editor;
import org.fpdev.apps.cart.gui.CartGUI;
import org.fpdev.apps.cart.gui.StylePreviewPanel;
import org.fpdev.apps.cart.network.Line;
import org.fpdev.apps.cart.network.LineStyle;
import org.fpdev.util.gui.GUIFactory;

/**
 *
 * @author demory
 */
public class LinesFrame extends ControlFrame implements ActionListener {

  private JPanel listPanel_;
  private JButton newBtn_, delBtn_, editBtn_;

  private SortedMap<Line, LineRow> lineRows_;
  private LineRow selectedRow_;
  private JComboBox styleSelector_;
  private Map<Integer, LineStyle> styleLookup_;

  //boolean supressSetStyleEvent_ = false;

  public LinesFrame(CartEventProcessor cep, CartGUI gui, ControlFrameManager cfm) {
    super(cep, gui, cfm, "Lines");

    lineRows_ = new TreeMap<Line, LineRow>();

    listPanel_ = GUIFactory.newColumnPanel();
    JPanel listPanelWrapper = new JPanel(new BorderLayout());
    listPanelWrapper.add(listPanel_, BorderLayout.NORTH);
    JScrollPane scrollPane = new JScrollPane(listPanelWrapper);
    scrollPane.setBorder(new CompoundBorder(new EmptyBorder(0, 5, 5, 5), new BevelBorder(BevelBorder.LOWERED)));

    newBtn_ = GUIFactory.newButton("N", 30, this);
    delBtn_ = GUIFactory.newButton("D", 30, this);
    editBtn_ = GUIFactory.newButton("E", 30, this);
    styleSelector_ = GUIFactory.newComboBox(0); //new JComboBox();
    styleSelector_.addActionListener(this);
    /*styleSelector_.addItemListener(new ItemListener() {
      public void itemStateChanged(ItemEvent e) {
        if(e.getStateChange() == ItemEvent.SELECTED && styleSelector_.hasFocus()) System.out.println("iSC");
      }
    });*/
    JPanel buttonRow = GUIFactory.newRowPanel();
    //buttonRow.add(Box.createHorizontalGlue());
    buttonRow.add(newBtn_);
    buttonRow.add(delBtn_);
    buttonRow.add(editBtn_);
    buttonRow.add(styleSelector_);
    //buttonRow.add(Box.createHorizontalGlue());

    JPanel mainPanel = new JPanel(new BorderLayout());
    mainPanel.add(scrollPane, BorderLayout.CENTER);
    mainPanel.add(buttonRow, BorderLayout.NORTH);

    mainPanel.setBorder(new CompoundBorder(new LineBorder(Color.gray), new EmptyBorder(3, 0, 3, 0)));

    setLayout(new BorderLayout());
    add(mainPanel, BorderLayout.CENTER);
    //add(mainPanel, BorderLayout.CENTER);
    pack();
    setSize(200, 200);
  }

  public void actionPerformed(ActionEvent e) {
    if(e.getSource() == newBtn_) {
      cep_.handleEvent(new CartEvent(CartEvent.Type.CREATE_LINE));
    }
    if(e.getSource() == delBtn_) {
      cep_.handleEvent(new CartEvent(CartEvent.Type.DELETE_LINE));
      selectedRow_ = null;
      refreshList();
    }
    if(e.getSource() == editBtn_) {
    }
    if(e.getSource() == styleSelector_ && styleSelector_.isFocusable() && styleSelector_.isFocusOwner()) {
      //System.out.println("foo "+e.paramString());
      CartEvent event = new CartEvent(CartEvent.Type.SET_LINE_STYLE);
      event.setProperty("line", getSelectedLine());
      event.setProperty("style", styleLookup_.get(styleSelector_.getSelectedIndex()));
      cep_.handleEvent(event);
    }
  }

  public Line getSelectedLine() {
    return selectedRow_ == null ? null : selectedRow_.line_;
  }

  public void refreshList() {
    listPanel_.removeAll();
    for(LineRow row : lineRows_.values()) {
      listPanel_.add(row);

      if(row == selectedRow_)
        row.setBorder(new CompoundBorder(new EmptyBorder(2, 2, 2, 2), new CompoundBorder(new LineBorder(Color.red, 2), new EmptyBorder(2, 2, 2, 2))));
      else
        row.setBorder(new EmptyBorder(3, 3, 3, 3));
      
    }
    listPanel_.revalidate();
  }

  public void refreshStyles(List<LineStyle> styles) {
    styleSelector_.setFocusable(false);
    styleSelector_.removeAllItems();
    styleLookup_ = new HashMap<Integer, LineStyle>();
    styleSelector_.addItem("DEFAULT");
    LineStyle def = new LineStyle(LineStyle.Preset.DEFAULT);
    styleLookup_.put(0, def);
    int i = 1;
    for(LineStyle style : styles) {
      styleSelector_.addItem(style.getStyleName());
      styleLookup_.put(i++, style);
    }
    styleSelector_.setFocusable(true);
  }

  public LineRow addLine(Line line) {
    LineRow row = new LineRow(line);
    lineRows_.put(line, row);
    refreshList();
    return row;
  }

  public void removeLine(Line line) {
    lineRows_.remove(line);
    refreshList();
  }

  public void clear() {
    lineRows_ = new TreeMap<Line, LineRow>();
    selectedRow_ = null;
    refreshList();
  }

  public void updateRow(Line line) {
    LineRow row = lineRows_.get(line);
    row.lineModified();
    row.repaint();
  }

  public void rowSelected(LineRow row) {

    selectedRow_ = row;

    if(selectedRow_ != null) {
      selectedRow_.line_.setHighlighted(false);
      selectedRow_.line_.setHighlighted(true);
      gui_.getActiveEditorFrame().getEditor().setSelectedLine(row.line_);
      cep_.handleEvent(new CartEvent(Type.REFRESH_CANVAS));

      int i=0;
      for(LineStyle style: styleLookup_.values()) {
        if(row.line_.getStyle().getID() == style.getID()) {
          styleSelector_.setSelectedIndex(i);
          break;
        }
        i++;
      }
    }

    editBtn_.setEnabled(selectedRow_ != null);
    delBtn_.setEnabled(selectedRow_ != null);
    styleSelector_.setEnabled(selectedRow_ != null);

    refreshList();
  }


  @Override
  public void editorChanged(Editor oldEd, Editor newEd) {
    //if(oldEd != null) oldEd.setSelectedLine(selectedLine);
    clear();
    if(newEd == null) return;
    for(Line line : newEd.getDocument().getNetwork().getLines()) {
      LineRow row = addLine(line);
      row.checkbox_.setSelected(line.isEnabled());
    }
    refreshStyles(newEd.getDocument().getStyles().getList());
    rowSelected(null);
  }

  public class LineRow extends JPanel {

    private Line line_;

    private JCheckBox checkbox_;
    private StylePreviewPanel swatch_;

    public LineRow(Line line) {
      super(new BorderLayout());

      line_ = line;

      checkbox_ = new JCheckBox();
      checkbox_.setSelected(true);
      checkbox_.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          //gui_.getCanvas().repaint();
          line_.setEnabled(checkbox_.isSelected());
          cep_.handleEvent(new CartEvent(CartEvent.Type.REFRESH_CANVAS));
        }
      });

      swatch_ = new StylePreviewPanel(line.getStyle(), 30, 18, Color.gray, 1, true);

      JPanel leftPanel = GUIFactory.newRowPanel();
      leftPanel.add(checkbox_);
      leftPanel.add(Box.createHorizontalStrut(4));
      leftPanel.add(swatch_);
      leftPanel.add(Box.createHorizontalStrut(4));


      // contruct row
      add(leftPanel, BorderLayout.WEST);
      add(new JLabel(line_.getName()), BorderLayout.CENTER);

      // add listeners

      addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
          rowSelected(LineRow.this);
        }

      });
    }

    public void lineModified() {
      swatch_.setStyleInfo(line_.getStyle());
    }

    /*public boolean lineEnabled() {
      return checkbox_.isSelected();
    }*/
  }

}
